package com.sunyw.xyz.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.beat.chatgpt.enums.AIClientTypeEnum;
import com.beat.chatgpt.model.UnifyChatCompletion;
import com.beat.chatgpt.model.UnifyCompletion;
import com.beat.chatgpt.provider.UnifyAIClientService;
import com.beat.chatgpt.provider.UnifyAIClientServiceImpl;
import com.beat.chatgpt.provider.openai.OpenAIClient;
import com.beat.chatgpt.provider.openai.dto.common.Choice;
import com.beat.chatgpt.provider.openai.dto.completions.ChatCompletion;
import com.beat.chatgpt.provider.openai.dto.completions.ChatMessages;
import com.beat.chatgpt.provider.openai.dto.completions.CompletionResponse;
import com.beat.chatgpt.provider.openai.dto.proxy.ProxyModel;
import com.sunyw.xyz.model.*;
import lombok.extern.slf4j.Slf4j;
import okhttp3.ResponseBody;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import retrofit2.Call;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class OpenAIService {
    @Value("${openai.token}")
    private String openAiToken;

    @Value("${openai.timeout}")
    private Integer timeOut;

    @Value("${feishu.gpt.appid}")
    private String gptAppId;

    @Value("${feishu.gpt.appSecret}")
    private String gptAppSecret;

    private String baseUrl = "https://openai.beatchat.cn/";

    private UnifyAIClientService unifyAIClientService;

    public OpenAIService() {
        unifyAIClientService = new UnifyAIClientServiceImpl();
        Map<AIClientTypeEnum, Map<String, Object>> configs = new HashMap<>();
        Map<String, Object> openAIconfig = new HashMap<>();
        openAIconfig.put("apiKey", "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");
        configs.put(AIClientTypeEnum.OPENAI, openAIconfig);

        Map<String, Object> aliyunAIconfig = new HashMap<>();
        aliyunAIconfig.put("apiKey", "sk-62a39126a35c4f7883e9e249b27c44c4");
        configs.put(AIClientTypeEnum.ALIYUN_AI, aliyunAIconfig);

        Map<String, Object> azureAIConfig = new HashMap<>();
        azureAIConfig.put("apiKey", "b8b9380ff0a042c4b7672526aeca8273");
        azureAIConfig.put("endpoint", "https://jiansyun-openai-japan.openai.azure.com/");
        configs.put(AIClientTypeEnum.AZURE_AI, azureAIConfig);

        Map<String, Object> baiduAIConfig = new HashMap<>();
        baiduAIConfig.put("clientId", "Z1Im1dZy4G9vOMG7eBdE1ReP");
        baiduAIConfig.put("clientSecret", "CLM3ba7i9oz3VsWryhAeFnKR6ktS9Nhb");
        baiduAIConfig.put("grantType", "client_credentials");
        configs.put(AIClientTypeEnum.BAIDU_AI, baiduAIConfig);
        unifyAIClientService.InitServices(configs);
    }

    //    @Async("threadPoolTaskExecutor")
    public String completionsHandle(CompletionsCreateModel completionsCreateModel) {

        String result = "";
        OpenAIClient openAIClient = new OpenAIClient(openAiToken, baseUrl, timeOut, timeOut, timeOut, null);
        try {
            CompletionResponse completionResponse = openAIClient.chatCompletions(completionsCreateModel.getPrompt(), ChatCompletion.Model.GPT_35_TURBO.getName());
            if (completionResponse != null && completionResponse.getChoices() != null) {
                log.info("返回消息:" + JSON.toJSONString(completionResponse));
                for (Choice choice : completionResponse.getChoices()) {
                    result += choice.getMessage().getContent();
                }
            } else {
                result = "我出现了一些错误,这可能是因为网络不稳定导致的,重新提问一下或许就可以获取到你想要的回答!";
                if (completionResponse == null) {
                    log.warn("请检查获取请求数据为空");
                }
            }
        } catch (Exception e) {
            result = "我出现了一些错误,这可能是因为网络不稳定导致的,重新提问一下或许就可以获取到你想要的回答!";
        }

        if (StringUtils.isBlank(result)) {
            result = "我出现了一些错误,这可能是因为网络不稳定导致的,重新提问一下或许就可以获取到你想要的回答!";
            log.warn("请检查获取请求数据为空");
        }
        return result;
    }

    public Result<String> completionsHandleEx(String prompt) {

        Result<String> r = new Result<>();
        String result = "";
        OpenAIClient openAIClient = new OpenAIClient(openAiToken, baseUrl, timeOut, timeOut, timeOut, null);
        try {
            CompletionResponse completionResponse = openAIClient.chatCompletions(prompt, ChatCompletion.Model.GPT_35_TURBO.getName());
            if (completionResponse != null && completionResponse.getChoices() != null) {
                log.info("返回消息:" + JSON.toJSONString(completionResponse));
                for (Choice choice : completionResponse.getChoices()) {
                    result += choice.getMessage().getContent();
                }
            } else {
                result = "";
                if (completionResponse == null) {
                    log.warn("请检查获取请求数据为空");
                } else {
                    return r.fail(result, -1, completionResponse.getError().getMessage());
                }
            }
        } catch (Exception e) {
            result = "";
        }

        if (StringUtils.isBlank(result)) {
            result = "";
            log.warn("请检查获取请求数据为空");
        }

        if (StringUtils.isBlank(result)) {
            return r.fail(result, 1001, "请求数据为空,请重新尝试");
        }

        return r.ok(result);
    }

    public void chatStream(ChatCompletionDTO chatCompletion) {

    }

    public CompletionResponse chatCompletion(ChatCompletionDTO chatCompletionDTO) {
        CompletionResponse completionResponse = null;
        List<ChatMessages> messages = BeanUtil.copyToList(chatCompletionDTO.getMessages(), ChatMessages.class);
        OpenAIClient openAIClient = new OpenAIClient(openAiToken, baseUrl, timeOut, timeOut, timeOut, null);
        try {
            log.info("请求消息:" + JSON.toJSONString(chatCompletionDTO));

            ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).build();
            chatCompletion.setStream(chatCompletionDTO.isStream());
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getMaxTokens())) {
                chatCompletion.setMaxTokens(chatCompletionDTO.getMaxTokens());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getTemperature())) {
                chatCompletion.setTemperature(chatCompletionDTO.getTemperature());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getUser())) {
                chatCompletion.setUser(chatCompletionDTO.getUser());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getPresencePenalty())) {
                chatCompletion.setPresencePenalty(chatCompletionDTO.getPresencePenalty());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getFrequencyPenalty())) {
                chatCompletion.setFrequencyPenalty(chatCompletionDTO.getFrequencyPenalty());
            }
            log.info("消息转换:" + JSON.toJSONString(chatCompletion));
            completionResponse = openAIClient.chatCompletions(chatCompletion);
            if (completionResponse != null && completionResponse.getChoices() != null) {
                log.info("返回消息:" + JSON.toJSONString(completionResponse));

            } else {

                if (completionResponse == null) {
                    log.warn("请检查获取请求数据为空");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return completionResponse;
    }

    /**
     * 返回流
     *
     * @param chatCompletionDTO
     * @return
     */
    public InputStream chatCompletionStream(ChatCompletionDTO chatCompletionDTO) {
        InputStream inputStream = null;
        ProxyModel proxyModel = new ProxyModel();
//        proxyModel.setIp("127.0.0.1");
//        proxyModel.setPort(7890);
//        proxyModel.setIp("104.234.230.248");
//        proxyModel.setPort(12323);
//        proxyModel.setUsername("14a8c83c83db5");
//        proxyModel.setPassword("99dd780517");
        List<ChatMessages> messages = BeanUtil.copyToList(chatCompletionDTO.getMessages(), ChatMessages.class);
        OpenAIClient openAIClient = new OpenAIClient(openAiToken, baseUrl, timeOut, timeOut, timeOut, null);
        try {
            log.info("请求消息:" + JSON.toJSONString(chatCompletionDTO));
            ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).build();
            chatCompletion.setStream(chatCompletionDTO.isStream());
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getMaxTokens())) {
                chatCompletion.setMaxTokens(chatCompletionDTO.getMaxTokens());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getTemperature())) {
                chatCompletion.setTemperature(chatCompletionDTO.getTemperature());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getUser())) {
                chatCompletion.setUser(chatCompletionDTO.getUser());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getPresencePenalty())) {
                chatCompletion.setPresencePenalty(chatCompletionDTO.getPresencePenalty());
            }
            if (ObjectUtil.isNotEmpty(chatCompletionDTO.getFrequencyPenalty())) {
                chatCompletion.setFrequencyPenalty(chatCompletionDTO.getFrequencyPenalty());
            }
            log.info("消息转换:" + JSON.toJSONString(chatCompletion));
            Call<ResponseBody> completions = openAIClient.chatCompletionsStream(chatCompletion);
            ResponseBody body = null;
            try {
                body = completions.execute().body();
            } catch (IOException e) {
                e.printStackTrace();
            }
            inputStream = body.byteStream();
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return inputStream;
    }


    public UnifyCompletion unifyChatCompletion(UnifyChatCompletion unifyChatCompletion) {
        log.info("消息转换:" + JSON.toJSONString(unifyChatCompletion));
        UnifyCompletion unifyCompletion = unifyAIClientService.completions(unifyChatCompletion);
        try {
            if (unifyCompletion != null && unifyCompletion.getChoices() != null) {
                log.info("返回消息:" + JSON.toJSONString(unifyCompletion));

            } else {

                if (unifyCompletion == null) {
                    log.warn("请检查获取请求数据为空");
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return unifyCompletion;
    }

    public InputStream unifyChatCompletionStream(UnifyChatCompletion unifyChatCompletion) {
        log.info("消息转换:" + JSON.toJSONString(unifyChatCompletion));
        unifyChatCompletion.setStream(true);
        return unifyAIClientService.completionsStream(unifyChatCompletion);
    }
}
